package com.frinder.official.akka.routing;

import akka.actor.ActorSystem;
import akka.actor.OneForOneStrategy;
import akka.actor.SupervisorStrategy;
import akka.dispatch.Dispatchers;
import akka.japi.pf.DeciderBuilder;
import akka.routing.DefaultResizer;
import akka.routing.PoolBase;
import akka.routing.Resizer;
import akka.routing.Router;
import com.typesafe.config.Config;
import scala.Option;
import scala.concurrent.duration.Duration;

import java.util.concurrent.TimeUnit;

import static akka.actor.SupervisorStrategy.*;

/**
 * Created by frinder on 2017/9/30.
 * <p>
 * simulation crc32 get remainder to split different request to dedicated routee
 */
public class Crc32RoutingPool extends PoolBase {

    private final int roundSize;

    public Crc32RoutingPool(int roundSize) {
        this.roundSize = roundSize;
    }

    public Crc32RoutingPool(Config config) {
        this(config.getInt("nr-of-instances"));
    }

    @Override
    public int nrOfInstances(ActorSystem sys) {
        return roundSize;
    }

    @Override
    public Option<Resizer> resizer() {
        Option option = Option.apply(new DefaultResizer(roundSize, roundSize));
        return option;
    }

    @Override
    public SupervisorStrategy supervisorStrategy() {
        return new OneForOneStrategy(10,
                Duration.create(1, TimeUnit.MINUTES),
                DeciderBuilder.matchAny(o -> escalate()).build()
        );
    }

    @Override
    public Router createRouter(ActorSystem system) {
        return new Router(new Crc32RoutingLogic(roundSize));
    }

    @Override
    public String routerDispatcher() {
        return Dispatchers.DefaultDispatcherId();
    }
}
